package com.whfc.wxmp.api.sys.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.whfc.base.entity.AppMessage;
import com.whfc.base.enums.AppModuleType;
import com.whfc.base.service.MessageService;
import com.whfc.common.constant.QueueConst;
import com.whfc.common.enums.*;
import com.whfc.common.exception.BizException;
import com.whfc.common.result.PageData;
import com.whfc.common.result.ResultEnum;
import com.whfc.common.util.NumberParser;
import com.whfc.emp.dto.AppAttachDTO;
import com.whfc.emp.dto.AppEmpDTO;
import com.whfc.emp.dto.AppFenceDTO;
import com.whfc.emp.entity.*;
import com.whfc.emp.entity.AppWorkPlan;
import com.whfc.emp.service.*;
import com.whfc.entity.dto.Apply.rep.*;
import com.whfc.entity.dto.Apply.req.*;
import com.whfc.entity.dto.msg.AppMsgToUserDTO;
import com.whfc.entity.dto.msg.PushMsgDTO;
import com.whfc.env.dto.EnvDustDataDTO;
import com.whfc.env.dto.GasDetectionQueryReq;
import com.whfc.env.dto.GasDetectionResultDTO;
import com.whfc.env.service.EnvDataService;
import com.whfc.env.service.EnvWarnDataService;
import com.whfc.fuum.entity.SysUser;
import com.whfc.fuum.entity.WxUser;
import com.whfc.fuum.service.SysDeptService;
import com.whfc.fuum.service.SysUserService;
import com.whfc.fuum.service.SysWorkAreaService;
import com.whfc.mach.entity.AppMach;
import com.whfc.mach.service.AppMachService;
import com.whfc.wxmp.api.sys.dto.ConfirmRequestDTO;
import com.whfc.wxmp.api.sys.service.WxWorkPlanService;
import com.whfc.wxmp.dto.ApprovalRecordDTO;
import com.whfc.wxmp.dto.WorkPlanDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.jetbrains.annotations.NotNull;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class WxWorkPlanServiceImpl implements WxWorkPlanService {


    @DubboReference(interfaceClass = AppWorkPlanService.class, version = "1.0.0", timeout = 30000)
    private AppWorkPlanService appWorkPlanService;

    @DubboReference(interfaceClass = AppEntryApplicationService.class, version = "1.0.0", timeout = 30000)
    private AppEntryApplicationService appEntryApplicationService;

    @DubboReference(interfaceClass = SysWorkAreaService.class, version = "1.0.0", timeout = 30000)
    private SysWorkAreaService sysWorkAreaService;

    @DubboReference(interfaceClass = AppMachService.class, version = "1.0.0", timeout = 30000)
    private AppMachService appMachService;

    @DubboReference(interfaceClass = SysDeptService.class, version = "1.0.0")
    private SysDeptService sysDeptService;

    @DubboReference(interfaceClass = ApprovalRecordService.class, version = "1.0.0", timeout = 30000)
    private ApprovalRecordService approvalRecordService;

    @DubboReference(interfaceClass = ConfirmationRecordService.class, version = "1.0.0")
    private ConfirmationRecordService confirmationRecordService;

    @DubboReference(interfaceClass = SysUserService.class, version = "1.0.0", timeout = 30000)
    private SysUserService sysUserService;

    @DubboReference(interfaceClass = AppEmpService.class, version = "1.0.0", timeout = 30000)
    private AppEmpService appEmpService;

    @DubboReference(interfaceClass = AppContractService.class, version = "1.0.0", timeout = 30000)
    private AppContractService appContractService;

    @DubboReference(interfaceClass = AppEmpHealthReportService.class, version = "1.0.0", timeout = 30000)
    private AppEmpHealthReportService appEmpHealthReportService;

    @DubboReference(interfaceClass = AppFenceService.class, version = "1.0.0", timeout = 10 * 10000)
    private AppFenceService appFenceService;

    @DubboReference(interfaceClass = EnvDataService.class, version = "1.0.0", timeout = 30000)
    private EnvDataService envDataService;

    @DubboReference(interfaceClass = EnvWarnDataService.class, version = "1.0.0", timeout = 30000)
    private EnvWarnDataService envWarnDataService;

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Override
    public String saveWorkPlan(WxUser user, WorkPlanCreatePlanReq req) {
        if (req.getId() == null) {
            // 查询项目下的个个机构管理人员
            List<UserDeptDTO> userDeptDTOS = sysDeptService.queryMessage(Integer.valueOf(req.getDeptId()));
            AppWorkPlan record = new AppWorkPlan();
            BeanUtils.copyProperties(req, record);
            List<String> constructionPersonnelIds = req.getConstructionPersonnelIds();
            String idsStr = constructionPersonnelIds == null || constructionPersonnelIds.isEmpty()
                    ? ""
                    : constructionPersonnelIds.stream()
                    .map(String::valueOf)  // 将每个元素转为字符串
                    .collect(Collectors.joining(","));  // 用逗号拼接
            record.setConstructionWorkers(idsStr);

            List<String> equipmentIds = req.getEquipmentIds();
            String equipmentIdsStr = equipmentIds == null || equipmentIds.isEmpty()
                    ? ""
                    : equipmentIds.stream()
                    .map(String::valueOf)  // 将每个元素转为字符串
                    .collect(Collectors.joining(","));  // 用逗号拼接
            record.setMachCmd(equipmentIdsStr);
            
            // 处理深坑作业报警设备
            List<String> envDustIds = req.getEnvDustIds();
            String envDustIdsStr = (envDustIds == null || envDustIds.isEmpty())
                    ? ""
                    : envDustIds.stream().collect(Collectors.joining(","));
            record.setEnvDustIds(envDustIdsStr);
            
            // 设置深坑作业标识
            record.setIsDeepWork(req.getIsDeepWork());
            
            setGuardian(req, record);

            record.setCreateUserId(user.getId());
            req = appWorkPlanService.insertSelective(record);
            if (req.getId() == null) {
                return "提交失败";
            }
//            List<AppMessage> appMessages = new ArrayList<>();
            if (!CollectionUtils.isEmpty(userDeptDTOS)) {
                for (UserDeptDTO userDept : userDeptDTOS) {
                    if (Objects.equals(userDept.getUserType(), SysUserUserType.OWNER.getValue())
                            || Objects.equals(userDept.getUserType(), SysUserUserType.SUPERVISOR.getValue())
                            || Objects.equals(userDept.getUserType(), SysUserUserType.GENERAL_CONTRACTOR.getValue())
                            || Objects.equals(userDept.getUserType(), SysUserUserType.SUB_CONTRACTOR.getValue())
                    ) {
                        // 存储审核信息
                        ApprovalRecord approvalRecord = new ApprovalRecord();
                        approvalRecord.setApplicationId(req.getId());
                        approvalRecord.setApproverType(userDept.getUserType());
                        approvalRecord.setApproverId(userDept.getUserId());
                        approvalRecord.setReviewType(ReviewType.PLAN_REVIEW.getValue());
                        approvalRecord.setApprovalResult(ApprovalResult.PENDING.getValue());
                        approvalRecordService.insertApprovalRecord(approvalRecord);

                        // 人员入场申给审批人发送消息提醒
                        sendWorkPlanMessage(userDept, record);
                    }

                }
            }
        }else {
            AppWorkPlan record = appWorkPlanService.selectById(req.getId());
            if (record != null){
                setGuardian(req, record);
                appWorkPlanService.updateSelectiveById(record);
            }
        }
        return "提交成功";
    }

    private static void setGuardian(WorkPlanCreatePlanReq req, AppWorkPlan record) {
        List<String> guardianId1 = req.getGuardian1Id();
        String idsStr1 = guardianId1 == null || guardianId1.isEmpty()
                ? ""
                : guardianId1.stream()
                .map(String::valueOf)  // 将每个元素转为字符串
                .collect(Collectors.joining(","));  // 用逗号拼接
        record.setGuardian1Id(idsStr1);

        List<String> guardianId2 = req.getGuardian1Id();
        String idsStr2 = guardianId2 == null || guardianId2.isEmpty()
                ? ""
                : guardianId2.stream()
                .map(String::valueOf)  // 将每个元素转为字符串
                .collect(Collectors.joining(","));  // 用逗号拼接
        record.setGuardian1Id(idsStr2);

        List<String> guardianId3 = req.getGuardian1Id();
        String idsStr3 = guardianId3 == null || guardianId3.isEmpty()
                ? ""
                : guardianId3.stream()
                .map(String::valueOf)  // 将每个元素转为字符串
                .collect(Collectors.joining(","));  // 用逗号拼接
        record.setGuardian1Id(idsStr3);

        List<String> guardianId4 = req.getGuardian1Id();
        String idsStr4 = guardianId4 == null || guardianId4.isEmpty()
                ? ""
                : guardianId4.stream()
                .map(String::valueOf)  // 将每个元素转为字符串
                .collect(Collectors.joining(","));  // 用逗号拼接
        record.setGuardian1Id(idsStr4);
    }

    /**
     * 使用MQ发送工作计划审批消息
     * @param userDept 审批人信息
     * @param record 工作计划记录
     */
    private void sendWorkPlanMessage(UserDeptDTO userDept, AppWorkPlan record) {
        if (userDept == null || userDept.getUserType().equals(SysUserUserType.COMMON.getValue())) return;

        // 创建接收人列表
        List<AppMsgToUserDTO> toUserList = new ArrayList<>();
        AppMsgToUserDTO userDTO = new AppMsgToUserDTO();
        userDTO.setUserId(userDept.getUserId());
        userDTO.setUsername(userDept.getUserName());
        userDTO.setPhone(userDept.getPhone());
        userDTO.setDeptId(userDept.getDeptId());
//        userDTO.setDeptName(userDept.getDeptName());
        toUserList.add(userDTO);

        // 创建推送消息DTO
        PushMsgDTO pushMsgDTO = new PushMsgDTO();
        pushMsgDTO.setTitle("工作计划审批");
        pushMsgDTO.setContent("标题：" + record.getPlanName() + ",措施内容：" + record.getMeasures());
        pushMsgDTO.setDeptId(userDept.getDeptId());
        pushMsgDTO.setTime(new Date());
        pushMsgDTO.setModuleType(10);
        pushMsgDTO.setMsgObjectId("1");
        pushMsgDTO.setToUserList(toUserList);

        // 设置消息渠道：PC(3)和APP(1)
        List<Integer> msgChannelList = new ArrayList<>();
        msgChannelList.add(3); // PC
        msgChannelList.add(1); // APP
        pushMsgDTO.setMsgChannelList(msgChannelList);

        // 通过MQ发送消息
        amqpTemplate.convertAndSend(QueueConst.PUSH_MSG_EXCHANGE, "", JSON.toJSONString(pushMsgDTO));
    }

    @Override
    public  List<AppEntryApplication> queryEntryerId(WxUser user) {
        return appEntryApplicationService.selectByCreator(user.getId());
    }

    @Override
    public List<SafetyTrainingExamReq> queryConstructionWorkers(Integer id) {
        List<SafetyTrainingExamReq> safetyTrainingExamReqs = new ArrayList<>();
        AppEntryApplication entryPersonIds = appEntryApplicationService.selectByPrimaryKey(id);
        List<QueryEmpSysIdDto> appEmpIds = sysUserService.getAppEmpEmpNamesIdList(Arrays.asList(entryPersonIds.getEntryPersonId().split("/")));
        for (QueryEmpSysIdDto queryEmpSysId : appEmpIds) {
            AppEmpDTO empInfo = appEmpService.getEmpInfo(queryEmpSysId.getAppEmpId());
            empInfo.setEmpId(queryEmpSysId.getSysUserId());
            SafetyTrainingExamReq safetyTrainingExamReq = convertToExamReq(empInfo);
            safetyTrainingExamReqs.add(safetyTrainingExamReq);
        }

        return safetyTrainingExamReqs;
    }
    private SafetyTrainingExamReq convertToExamReq(AppEmpDTO empDTO) {
        SafetyTrainingExamReq req = new SafetyTrainingExamReq();

        // 基础信息映射
        req.setEmp_id(empDTO.getEmpId());
        req.setName(empDTO.getEmpName());
        req.setGender(convertGender(empDTO.getGender()));
        req.setCompany(empDTO.getCorpName());
        req.setPosition(empDTO.getWorkTypeName());
        req.setAddress(empDTO.getAddress());
        req.setHardwareNumber(empDTO.getSn());
        req.setExamStatus("未考试");

        // 合同信息
        List<AppAttachDTO> contractDTOs = appContractService.selectByEmpIdUrl(empDTO.getEmpId());
        req.setContractFileName(convertAttachList(contractDTOs));

        // 资质证书信息
        List<AppAttachDTO> certDTOs = appEmpService.selectByEmpIdUrl(empDTO.getEmpId());
        req.setQualificationCertificateNmae(convertAttachList(certDTOs));

        // 体检报告（类型1）
        List<AppAttachDTO> healthReportDTOs = appEmpHealthReportService.selectByEmpIdImg(empDTO.getEmpId(), "1");
        req.setMedicalReportNmae(convertAttachList(healthReportDTOs));

// 社保证明（类型2）
        List<AppAttachDTO> insuranceDTOs = appEmpHealthReportService.selectByEmpIdImg(empDTO.getEmpId(), "2");
        req.setSocialSecurityProofNmae(convertAttachList(insuranceDTOs));

        return req;
    }
    private List<Map<String, String>> convertAttachList(List<AppAttachDTO> attachList) {
        // 空集合直接返回空列表，避免后续流处理空指针
        if (CollectionUtils.isEmpty(attachList)) {
            return Collections.emptyList();
        }

        return attachList.stream()
                .filter(Objects::nonNull)
                .filter(dto ->
                        // 统一过滤条件：name和url非空且非空白
                        dto.getName() != null && !dto.getName().trim().isEmpty() &&
                                dto.getUrl() != null && !dto.getUrl().trim().isEmpty()
                )
                .map(dto -> {
                    Map<String, String> map = new HashMap<>(2);
                    map.put("name", dto.getName().trim());
                    map.put("url", dto.getUrl().trim());
                    return map;
                })
                .collect(Collectors.toList());
    }


    /**
     * 性别转换工具方法
     */
    private String convertGender(Integer gender) {
        return gender == null ? "未知" :
                gender == 1 ? "男" :
gender == 2 ? "女" : "未知";
    }

    @Override
    public List<RegionRep> queryWorkArea(Integer deptId) {
        return appFenceService.getWorkArea(deptId);
    }

    @Override
    public List<AppMach> queryMach(EquipmentIdReq req) {
        return appMachService.selectEquipmentList(req);
    }

    @Override
    public List<WorkPlanDTO> entryReview(WxUser user, AppEntryApplicationReq req) {
        //获取当前登录人的机构
        String integers = sysDeptService.selectDeptIdById(user.getId());
        List<Integer> pidList = NumberParser.parseCommaSeparatedNumbers(integers);

        List<WorkPlan> appWorkPlans = appWorkPlanService.selectWorkPlanListWithTimeRange(
                pidList, null,
                req.getCreateTimeBegin(), req.getCreateTimeEnd(),
                req.getStartTimeBegin(), req.getStartTimeEnd(),
                req.getEndTimeBegin(), req.getEndTimeEnd(), req.getAuditStatus());
        List<WorkPlanDTO> responses = build(appWorkPlans, user.getId());
        return responses;
    }

    private List<WorkPlanDTO> build(List<WorkPlan> appWorkPlans, Integer currentUserId){
        List<WorkPlanDTO> responses = new ArrayList<>();
        for (WorkPlan plan : appWorkPlans) {
            WorkPlanDTO response = new WorkPlanDTO();
            BeanUtils.copyProperties(plan, response);
            // 根据计划查询入场申请单
            AppEntryApplication entryApplication = appEntryApplicationService.selectByPrimaryKey(response.getEntryPermitId());
            // 获取班组长
            if (entryApplication != null){
                response.setTeamLeader(appEmpService.getEmpInfo(entryApplication.getTeamLeaderId()));
            }
            // 获取施工人员
            buildWorkers(response);
            // 设备清单
            if (response.getMachCmd() != null && !Objects.equals(response.getMachCmd(), "")) {
                if (!response.getMachCmd().contains(",")) {
                    response.setMachCmdsInfoList(Arrays.asList(response.getMachCmd()));
                } else {
                    response.setMachCmdsInfoList(Arrays.asList(response.getMachCmd().split(",")));
                }
            }
            if(response.getMachCmdsInfoList() != null){
                List<AppMach> appMaches = appMachService.selectByMach(response.getMachCmdsInfoList());
                List<String> machCmdsInfoList = new ArrayList<>();
                for (AppMach appMach : appMaches) {
                    machCmdsInfoList.add(appMach.getMachTypeName());
                }
                response.setMachCmdsInfoList(machCmdsInfoList);
            }

            // 区域
            List<String> regionList = new ArrayList<>();
            List<AppFenceDTO> appFenceDTOS = appFenceService.listByMsAppFence(response.getWorkAreaId());
            for (AppFenceDTO app : appFenceDTOS) {
                regionList.add(app.getName());
            }
            response.setRegionList(regionList);
            response.setWorkArea(appFenceService.listByMsAppFenceName(response.getWorkAreaId()));
            response.setCreator(sysUserService.getUserById(response.getCreateUserId()));
            buildGuardians(response);

            buildEnvDust(plan.getEnvDustIds(), response);

            // 审核状态
            List<ApprovalRecordDTO> approvalRecords = new ArrayList<>();
            List<ApprovalRecord> approvalRecordList = approvalRecordService.selectRecordByApplyIdAndAuditType(response.getId(),
                    ReviewType.PLAN_REVIEW.getValue());
            Map<Integer, Boolean> needApproval = new HashMap<>();
            for (ApprovalRecord approvalRecord : approvalRecordList) {
                ApprovalRecordDTO recordDTO = new ApprovalRecordDTO();
                BeanUtils.copyProperties(approvalRecord, recordDTO);
//                recordDTO.setApplicantUser(applicant);
                // 4、根据审核人id查询审核人信息
                SysUser approvalUser = sysUserService.getUserById(approvalRecord.getApproverId());
                if (approvalUser == null || approvalUser.getUserType() == null)
                    continue;
                recordDTO.setApprovalUser(approvalUser);
                approvalRecords.add(recordDTO);
                if (approvalRecord.getApprovalResult().equals(ApprovalResult.PENDING.getValue())
                        && (!needApproval.containsKey(approvalUser.getUserType())
                        || needApproval.get(approvalUser.getUserType()) != false)) {
                    needApproval.put(approvalUser.getUserType(), true);
                } else if (approvalRecord.getApprovalResult().equals(ApprovalResult.APPROVE.getValue())) {
                    needApproval.put(approvalUser.getUserType(), false);
                }
            }
            // 按审核人类型倒序排列
            approvalRecords.sort((o1, o2) -> o2.getApprovalUser().getUserType() - o1.getApprovalUser().getUserType());
            // 简易版工作流 计算当前审核节点
            Integer approvalStep = SysUserUserType.SUPERVISOR.getValue();
            needApproval = needApproval.entrySet().stream()
                    .sorted(Map.Entry.<Integer, Boolean>comparingByKey().reversed())
                    .collect(Collectors.toMap(
                            Map.Entry::getKey,
                            Map.Entry::getValue,
                            (e1, e2) -> e1, // 合并函数，如果有重复key
                            LinkedHashMap::new // 保持排序顺序
                    )); // 按照key倒序排列
            Optional<Integer> firstFalseKey = needApproval.entrySet()
                    .stream()
                    .filter(Map.Entry::getValue) // value == true
                    .map(Map.Entry::getKey)
                    .findFirst();
            if (firstFalseKey.isPresent()) {
                approvalStep = firstFalseKey.get();
            }
            // 设置当前审核节点审核人员审核权限
            for (ApprovalRecordDTO dto : approvalRecords) {
                if (dto.getApprovalResult().equals(ApprovalResult.PENDING.getValue())
                        && dto.getApprovalUser().getUserType().equals(approvalStep)) {
                    dto.setFlag(true);
                    if (dto.getApprovalUser().getId().equals(currentUserId)) {
                        response.setFlag(true);
                    }
                } else {
                    dto.setFlag(false);
                }
            }

            response.setApprovalRecords(approvalRecords);

            responses.add(response);
        }
        return responses;
    }

    private void buildWorkers(WorkPlanDTO response) {
        List<String> sysUserIds = new ArrayList<>();
        if (response.getConstructionWorkers() != null && !Objects.equals(response.getConstructionWorkers(), "")) {
            if (!response.getConstructionWorkers().contains(",")) {
                sysUserIds.add(response.getConstructionWorkers());
            } else {
                sysUserIds.addAll(Arrays.asList(response.getConstructionWorkers().split(",")));
            }
        }
        if (!sysUserIds.isEmpty()) {
            List<QueryEmpSysIdDto> idList = sysUserService.getAppEmpEmpNamesIdList(sysUserIds);
            if (idList != null){
                List<Integer> temp = idList.stream().map(QueryEmpSysIdDto::getAppEmpId).collect(Collectors.toList());
                List<String> empIds = temp.stream()
                        .map(String::valueOf)
                        .collect(Collectors.toList());
                response.setWorkers(appEmpService.getEmpInfoList(empIds));
            }
        }
    }

    private void buildGuardians(WorkPlanDTO response) {
        List<String> uardianIds1 = new ArrayList<>();
        if (response.getGuardian1Id() != null && !Objects.equals(response.getGuardian1Id(), "")) {
            if (!response.getGuardian1Id().contains(",")) {
                uardianIds1.add(response.getGuardian1Id());
            } else {
                uardianIds1.addAll(Arrays.asList(response.getGuardian1Id().split(",")));
            }
        }
        if (!uardianIds1.isEmpty()){
            List<AppEmp> emps = appEmpService.getEmpInfoList(uardianIds1);
            if (emps != null && !emps.isEmpty()){
                response.setGuardian1(emps);
            }else {
                List<QueryEmpSysIdDto> idList1 = sysUserService.getAppEmpEmpNamesIdList(uardianIds1);
                if (idList1 != null && !idList1.isEmpty()){
                    List<Integer> temp = idList1.stream().map(QueryEmpSysIdDto::getAppEmpId).collect(Collectors.toList());
                    List<String> empIds = temp.stream()
                            .map(String::valueOf)
                            .collect(Collectors.toList());
                    response.setGuardian1(appEmpService.getEmpInfoList(empIds));
                }
            }
        }

        List<String> uardianIds2 = new ArrayList<>();
        if (response.getGuardian2Id() != null && !Objects.equals(response.getGuardian2Id(), "")) {
            if (!response.getGuardian2Id().contains(",")) {
                uardianIds2.add(response.getGuardian2Id());
            } else {
                uardianIds2.addAll(Arrays.asList(response.getGuardian2Id().split(",")));
            }
        }
        if (!uardianIds2.isEmpty()){
            List<QueryEmpSysIdDto> idList2 = sysUserService.getAppEmpEmpNamesIdList(uardianIds2);
            if (idList2 != null && !idList2.isEmpty()){
                List<Integer> temp = idList2.stream().map(QueryEmpSysIdDto::getAppEmpId).collect(Collectors.toList());
                List<String> empIds = temp.stream()
                        .map(String::valueOf)
                        .collect(Collectors.toList());
                response.setGuardian2(appEmpService.getEmpInfoList(empIds));
            }
        }

        List<String> uardianIds3 = new ArrayList<>();
        if (response.getGuardian3Id() != null && !Objects.equals(response.getGuardian3Id(), "")) {
            if (!response.getGuardian3Id().contains(",")) {
                uardianIds3.add(response.getGuardian3Id());
            } else {
                uardianIds3.addAll(Arrays.asList(response.getGuardian3Id().split(",")));
            }
        }
        if (!uardianIds3.isEmpty()){
            List<QueryEmpSysIdDto> idList3 = sysUserService.getAppEmpEmpNamesIdList(uardianIds3);
            if (idList3 != null && !idList3.isEmpty()){
                List<Integer> temp = idList3.stream().map(QueryEmpSysIdDto::getAppEmpId).collect(Collectors.toList());
                List<String> empIds = temp.stream()
                        .map(String::valueOf)
                        .collect(Collectors.toList());
                response.setGuardian3(appEmpService.getEmpInfoList(empIds));
            }
        }

        List<String> uardianIds4 = new ArrayList<>();
        if (response.getGuardian4Id() != null && !Objects.equals(response.getGuardian4Id(), "")) {
            if (!response.getGuardian4Id().contains(",")) {
                uardianIds4.add(response.getGuardian4Id());
            } else {
                uardianIds4.addAll(Arrays.asList(response.getGuardian4Id().split(",")));
            }
        }
        if (!uardianIds4.isEmpty()){
            List<QueryEmpSysIdDto> idList4 = sysUserService.getAppEmpEmpNamesIdList(uardianIds4);
            if (idList4 != null && !idList4.isEmpty()){
                List<Integer> temp = idList4.stream().map(QueryEmpSysIdDto::getAppEmpId).collect(Collectors.toList());
                List<String> empIds = temp.stream()
                        .map(String::valueOf)
                        .collect(Collectors.toList());
                response.setGuardian4(appEmpService.getEmpInfoList(empIds));
            }
        }
    }


    private void buildEnvDust(String envDustIdsStr, WorkPlanDTO response) {
        List<EnvDustDataDTO> dataDTOS = new ArrayList<>();
        List<String> envDustIds = new ArrayList<>();
        if (envDustIdsStr != null && !Objects.equals(envDustIdsStr, "")) {
            if (!envDustIdsStr.contains(",")) {
                envDustIds.add(envDustIdsStr);
            } else {
                envDustIds.addAll(Arrays.asList(envDustIdsStr.split(",")));
            }
        }
        if (!envDustIds.isEmpty()) {
            for (String strId: envDustIds){
                EnvDustDataDTO dustData = envDataService.getDustData(Integer.parseInt(strId));
                if (dustData != null) dataDTOS.add(dustData);
            }
        }
        response.setEnvDustIds(envDustIds);
        response.setEnvDusts(dataDTOS);
    }

    @Override
    public String confirmExit(Integer personOrDevice, Integer isExit, Integer planId) {
        return "";
    }

    @Override
    public Map<String,Object> confirm(WxUser user, ConfirmRequestDTO requestDTO) {
        // 参数校验
        if (requestDTO.getPlanId() == null) {
            throw new IllegalArgumentException("关联的工作计划不能为空");
        }
        if (requestDTO.getConfirmType() == null || (requestDTO.getConfirmType()!= 1 && requestDTO.getConfirmType()!= 2)) {
            throw new IllegalArgumentException("必须为1（到场）或2（离场）");
        }

        // 查询工作计划信息
        AppWorkPlan workPlan = appWorkPlanService.selectById(requestDTO.getPlanId());
        if (workPlan == null) {
            throw new IllegalArgumentException("工作计划不存在");
        }

        // 如果是深坑作业的到场确认，需要验证气体检测设备数据
        if (requestDTO.getConfirmType() == 1 && workPlan.getIsDeepWork() != null && workPlan.getIsDeepWork() == 1) {
            validateGasDetectionDevices(workPlan);
        }

        // 查询计划对应的记录 - 根据确认类型使用不同的查询条件
        ConfirmationRecord existRecord;
        if (requestDTO.getConfirmType() == 1) {
            // 到场确认：按工作计划ID和到场确认人查询
            ConfirmationRecord queryRecord = new ConfirmationRecord();
            queryRecord.setPlanId(requestDTO.getPlanId());
            queryRecord.setArrivalConfirmer(user.getId());
            List<ConfirmationRecord> records = confirmationRecordService.getByCondition(queryRecord);
            existRecord = records != null && !records.isEmpty() ? records.get(0) : null;
        } else {
            // 离场确认：按工作计划ID和离场确认人查询
            ConfirmationRecord queryRecord = new ConfirmationRecord();
            queryRecord.setPlanId(requestDTO.getPlanId());
            queryRecord.setDepartureConfirmer(user.getId());
            List<ConfirmationRecord> records = confirmationRecordService.getByCondition(queryRecord);
            existRecord = records != null && !records.isEmpty() ? records.get(0) : null;
        }
        boolean isNewRecord = (existRecord == null);

        try {
            if (requestDTO.getConfirmType() == 1) {
                if (isNewRecord) {
                    existRecord = new ConfirmationRecord();
                    existRecord.setPlanId(requestDTO.getPlanId());
                    existRecord.setArrivalStaff(requestDTO.getStaffStatus());
                    existRecord.setArrivalDevice(requestDTO.getDeviceStatus());
                    existRecord.setArrivalConfirmer(user.getId());
                    existRecord.setArrivalConfirmerName(user.getName());
                    existRecord.setArrivalConfirmTime(new Date());
                    existRecord.setWarnRecord(requestDTO.getWarnRecord()); // 设置危险气体数值
                    int i = confirmationRecordService.addRecord(existRecord);
                    if(i>0){
                        Map<String,Object> map = new HashMap<>();
                        map.put("state",requestDTO.getConfirmType());
                        return map;
                    }
                } else {
                    existRecord.setArrivalStaff(requestDTO.getStaffStatus());
                    existRecord.setArrivalDevice(requestDTO.getDeviceStatus());
                    existRecord.setArrivalConfirmer(user.getId());
                    existRecord.setArrivalConfirmerName(user.getName());
                    existRecord.setWarnRecord(requestDTO.getWarnRecord()); // 设置危险气体数值
                    existRecord.setArrivalConfirmTime(new Date());
                    int i = confirmationRecordService.updateRecord(existRecord);
                    if(i>0){
                        Map<String,Object> map = new HashMap<>();
                        map.put("state",requestDTO.getConfirmType());
                        return map;
                    }
                }
            }
            else {
                if (isNewRecord) {
                    throw new RuntimeException("离场确认失败：未找到" + requestDTO.getPlanId() + "的到场记录");
                }
                // 更新离场相关字段
                existRecord.setDepartureStaff(requestDTO.getStaffStatus());
                existRecord.setDepartureDevice(requestDTO.getDeviceStatus());
                existRecord.setDepartureConfirmer(user.getId());
                existRecord.setDepartureConfirmerName(user.getName());
                existRecord.setDepartureConfirmTime(new Date());
                int i = confirmationRecordService.updateRecord(existRecord);
                if(i>0){
                    Map<String,Object> map = new HashMap<>();
                    map.put("state",requestDTO.getConfirmType());
                    return map;
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return new HashMap<>();
    }

    /**
     * 验证气体检测设备数据
     * 深坑作业到场确认时，检测对应的工作计划中的env_dust_ids气体检测设备必须5分钟之内有检测数据上报，并且5分钟内没有报警数据
     * @param workPlan 工作计划
     */
    private void validateGasDetectionDevices(AppWorkPlan workPlan) {
        if (StringUtils.isBlank(workPlan.getEnvDustIds())) {
            throw new RuntimeException("深坑作业必须配置气体检测设备");
        }

        // 解析气体检测设备ID列表
        String[] deviceIdStrs = workPlan.getEnvDustIds().split(",");
        List<Integer> deviceIds = new ArrayList<>();
        for (String deviceIdStr : deviceIdStrs) {
            if (StringUtils.isNotBlank(deviceIdStr)) {
                try {
                    deviceIds.add(Integer.parseInt(deviceIdStr.trim()));
                } catch (NumberFormatException e) {
                    log.warn("无效的气体检测设备ID: {}", deviceIdStr);
                }
            }
        }

        if (deviceIds.isEmpty()) {
            throw new RuntimeException("深坑作业必须配置有效的气体检测设备");
        }

        // 计算5分钟时间范围
        Calendar calendar = Calendar.getInstance();
        Date endTime = calendar.getTime();
        calendar.add(Calendar.MINUTE, -5);
        Date startTime = calendar.getTime();

        // 验证每个气体检测设备
        for (Integer deviceId : deviceIds) {
            validateSingleGasDetectionDevice(deviceId, startTime, endTime);
        }
    }

    /**
     * 验证单个气体检测设备数据
     * @param deviceId 设备ID
     * @param startTime 开始时间（5分钟前）
     * @param endTime 结束时间（当前时间）
     */
    private void validateSingleGasDetectionDevice(Integer deviceId, Date startTime, Date endTime) {
        // 1. 检查5分钟内是否有检测数据上报
        List<EnvDustDataDTO> dataLogs = envDataService.getDustDataLog(deviceId, startTime, endTime);
        if (dataLogs == null || dataLogs.isEmpty()) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "气体检测设备(ID:" + deviceId + ")在5分钟内没有检测数据上报");
        }

        // 检查是否有有效数据（时间在5分钟内）
        boolean hasRecentData = false;
        for (EnvDustDataDTO data : dataLogs) {
            if (data.getTime() != null &&
                    data.getTime().after(startTime) &&
                    data.getTime().before(endTime)) {
                hasRecentData = true;
                break;
            }
        }

        if (!hasRecentData) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "气体检测设备(ID:" + deviceId + ")在5分钟内没有有效的检测数据");
        }

        // 2. 检查5分钟内是否有报警数据
        List<Integer> deptIds = new ArrayList<>();
        // 这里需要获取设备对应的部门ID，暂时使用空列表，实际应根据设备信息获取
        Integer warnCount = envWarnDataService.getWarnNumByState(deptIds, null, startTime, endTime, 0);
        if (warnCount != null && warnCount > 0) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "气体检测设备(ID:" + deviceId + ")在5分钟内有报警数据，无法进行到场确认");
        }
    }

    @Override
    public PageData<ConfirmationRecord> confirmList(WxUser user, ConfirmRequestDTO requestDTO) {
        return confirmationRecordService.getAllByPage(requestDTO.getPlanId(), requestDTO.getPageNum(), requestDTO.getPageSize());
    }

    @Override
    public String review(WxUser user, Integer status, Integer id) {
        // 获取当前审核记录
        ApprovalRecord currentRecord = approvalRecordService.getApprovalRecordById(id);
        if (status.equals(ApprovalResult.APPROVE.getValue())) {
            // 当前节点审批通过
            currentRecord.setApprovalResult(ApprovalResult.APPROVE.getValue());
            currentRecord.setApprovalTime(new Date());
            approvalRecordService.updateApprovalRecord(currentRecord);
            // 查看是否还有下一个节点
            Integer nextNode = getNextNode(currentRecord.getApproverType());
            // 设置当前申请记录状态
            AppWorkPlan appWorkPlan = appWorkPlanService.selectById(currentRecord.getApplicationId());
            if (nextNode == null) {
                // 没有下一个审核节点，申请审核通过
                appWorkPlan.setAuditStatus(ApprovalResult.APPROVE.getValue());
                appWorkPlan.setAuditUserId(user.getId());
                appWorkPlan.setAuditRemark(user.getName());
                appWorkPlanService.updateAuditStatus(appWorkPlan);
                sendMessage(appWorkPlan);
            } else if (appWorkPlan.getAuditStatus().equals(ApprovalResult.PENDING.getValue())) {
                appWorkPlan.setAuditStatus(ApprovalResult.APPROVING.getValue());
                appWorkPlan.setAuditUserId(user.getId());
                appWorkPlan.setAuditRemark(user.getName());
                appWorkPlanService.updateAuditStatus(appWorkPlan);
            }
            // 设置同类型其余审核记录：无需审核
            List<ApprovalRecord> approvalRecordList = approvalRecordService.selectRecordByApplyIdAndAuditType(currentRecord.getApplicationId(), ReviewType.PLAN_REVIEW.getValue());
            for (ApprovalRecord record: approvalRecordList){
                if (record.getApproverType().equals(currentRecord.getApproverType())){
                    if (!currentRecord.getId().equals(record.getId())) {
                        record.setApprovalResult(ApprovalResult.COMPLETED.getValue());
                        record.setApprovalTime(new Date());
                        approvalRecordService.updateApprovalRecord(record);
                    }
                }
            }
        } else if(status.equals(ApprovalResult.REJECT.getValue())){
            // 当前审批节点
            currentRecord.setApprovalResult(ApprovalResult.REJECT.getValue());
            currentRecord.setApprovalTime(new Date());
            approvalRecordService.updateApprovalRecord(currentRecord);
            // 申请记录
            AppWorkPlan appWorkPlan = appWorkPlanService.selectById(currentRecord.getApplicationId());
            appWorkPlan.setAuditStatus(ApprovalResult.REJECT.getValue());
            appWorkPlan.setAuditUserId(user.getId());
            appWorkPlan.setAuditRemark(user.getName());
            appWorkPlanService.updateAuditStatus(appWorkPlan);
        }
        return "审核成功!";
    }

    @Override
    public GasDetectionResultDTO getGasDetectionData(GasDetectionQueryReq queryReq) {
        return envDataService.getGasDetectionData(queryReq);
    }

    /**
     * 给入场人员发送短信
     * @param appWorkPlan
     */
    private void sendMessage(AppWorkPlan appWorkPlan) {
        AppEntryApplication appEntryApplication = appEntryApplicationService.selectByPrimaryKey(appWorkPlan.getEntryPermitId());
        if (appEntryApplication == null || appEntryApplication.getEntryPersonId() == null) return;
        String[] entryPersonIds = appEntryApplication.getEntryPersonId().split("/");
        String content = "您的入场工作计划已审批，入场时间："+appWorkPlan.getPlanStartTime()+",离场时间："+appWorkPlan.getPlanEndTime();
        String title = "入场工作计划审批";
//        List<AppMessage> appMessages = new ArrayList<>();
        
        // 创建接收人列表
        List<AppMsgToUserDTO> toUserList = new ArrayList<>();
        
        for (String entryPersonId : entryPersonIds){
            SysUser sysUser = sysUserService.getUserById(Integer.parseInt(entryPersonId));
            if (sysUser == null) continue;
            
            // 创建接收人DTO
            AppMsgToUserDTO userDTO = new AppMsgToUserDTO();
            userDTO.setUserId(sysUser.getId());
            userDTO.setUsername(sysUser.getUsername());
            userDTO.setPhone(sysUser.getPhone());
            userDTO.setDeptId(0);
            toUserList.add(userDTO);
            
            // 保留原有的AppMessage构建逻辑，用于兼容性
//            AppMessage appMessage = getAppMessage(content, title, sysUser);
//            appMessages.add(appMessage);
//
//            AppMessage msMessage = new AppMessage();
//            BeanUtils.copyProperties(appMessage, msMessage);
//            msMessage.setMsgChannel(AppWarnMsgChannel.MS.value());
//            appMessages.add(msMessage);
        }
        
        // 创建推送消息DTO并通过MQ发送
        if (!toUserList.isEmpty()) {
            PushMsgDTO pushMsgDTO = new PushMsgDTO();
            pushMsgDTO.setTitle(title);
            pushMsgDTO.setContent(content);
            pushMsgDTO.setDeptId(0);
            pushMsgDTO.setTime(new Date());
            pushMsgDTO.setModuleType(10);
            pushMsgDTO.setMsgObjectId("1");
            pushMsgDTO.setToUserList(toUserList);
            
            // 设置消息渠道：PC(3)和APP(1)
            List<Integer> msgChannelList = new ArrayList<>();
            msgChannelList.add(3); // PC
            msgChannelList.add(1); // APP
            pushMsgDTO.setMsgChannelList(msgChannelList);
            
            // 通过MQ发送消息
            amqpTemplate.convertAndSend(QueueConst.PUSH_MSG_EXCHANGE, "", JSON.toJSONString(pushMsgDTO));
        }

//        messageService.addAppMessage(appMessages);
    }

    @NotNull
//    private static AppMessage getAppMessage(String content, String title, SysUser sysUser) {
//        AppMessage appMessage = new AppMessage();
//        appMessage.setContent(content);
//        appMessage.setDeptId(0);
//        appMessage.setTitle(title);
//        appMessage.setToUserId(sysUser.getId());
//        appMessage.setToUserName(sysUser.getUsername());
//        appMessage.setToUserPhone(sysUser.getPhone());
//        appMessage.setMsgType(AppWarnModuleType.EMP.value());
//        appMessage.setMsgChannel(AppWarnMsgChannel.WXMP.value());
//        appMessage.setMsgObjectId("1");
//        appMessage.setModuleType(10);
//        appMessage.setTime(new Date());
//        appMessage.setState(0);
//        appMessage.setDelFlag(0);
//        appMessage.setCreateTime(new Date());
//        appMessage.setUpdateTime(new Date());
//        return appMessage;
//    }

    /**
     * 获取下一节点类型（如分包的下一节点是总包）
     */
    private Integer getNextNode(Integer currentType) {
        switch (currentType) {
            case 4:
                return 3;
            case 3:
                return 2;
            case 2:
                return 1;
            case 1:
                return 0;
            default:
                return null;
        }
    }
}